package yxy.apple.logger;

import org.slf4j.LoggerFactory;

public class Logger {
	private org.slf4j.Logger logger = null;

	public static enum Level {
		All, Trace, Debug, Info, Warn, Error, Off;
	}

	private static Level level = Level.Info;

	public static Level level() {
		return level;
	}

	public static boolean enabled(Level level) {
		return Logger.level.compareTo(level) <= 0;
	}

	public static void setLevel(Level level) {
		Logger.level = level;
	}

	public static Logger create(final Class<?> clazz) {
		return new Logger(LoggerFactory.getLogger(clazz));
	}

	private Logger(org.slf4j.Logger logger) {
		this.logger = logger;
	}

	private String format(String format, Object... args) {
		if (format != null) {
			return String.format(format, args);
		} else {
			return null;
		}
	}

	public void trace(String format, Object... args) {
		this.trace(null, format, args);
	}

	public void trace(Throwable throwable) {
		this.trace(throwable, throwable.getMessage());
	}

	public void trace(Throwable throwable, String format, Object... args) {
		if (level.ordinal() <= Level.Trace.ordinal()) {
			String message = this.format(format, args);
			this.logger.trace(message, throwable);
		}
	}

	public void debug(String format, Object... args) {
		this.debug(null, format, args);
	}

	public void debug(Throwable throwable) {
		this.debug(throwable, throwable.getMessage());
	}

	public void debug(Throwable throwable, String format, Object... args) {
		if (level.ordinal() <= Level.Debug.ordinal()) {
			String message = this.format(format, args);
			this.logger.debug(message, throwable);
		}
	}

	public void info(String format, Object... args) {
		this.info(null, format, args);
	}

	public void info(Throwable throwable) {
		this.info(throwable, throwable.getMessage());
	}

	public void info(Throwable throwable, String format, Object... args) {
		if (level.ordinal() <= Level.Info.ordinal()) {
			String message = this.format(format, args);
			this.logger.info(message, throwable);
		}
	}

	public void warn(String format, Object... args) {
		this.warn(null, format, args);
	}

	public void warn(Throwable throwable) {
		this.warn(throwable, throwable.getMessage());
	}

	public void warn(Throwable throwable, String format, Object... args) {
		if (level.ordinal() <= Level.Warn.ordinal()) {
			String message = this.format(format, args);
			this.logger.warn(message, throwable);
		}
	}

	public void error(String format, Object... args) {
		this.error(null, format, args);
	}

	public void error(Throwable throwable) {
		this.error(throwable, throwable.getMessage());
	}

	public void error(Throwable throwable, String format, Object... args) {
		if (level.ordinal() <= Level.Error.ordinal()) {
			String message = this.format(format, args);
			this.logger.error(message, throwable);
		}
	}

}
